package com.zeng.ssm.util;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.naming.NoNameCoder;
import com.thoughtworks.xstream.io.xml.CompactWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;
import com.thoughtworks.xstream.io.xml.XppDriver;
import com.thoughtworks.xstream.security.AnyTypePermission;

import java.io.Writer;
import java.nio.charset.StandardCharsets;

/**
 * xml报文解析工具类
 *
 * @author zengwanlin
 * @date 2022-12-21T10:36
 */
public class XStreamUtil {

    /**
     * 将javaBean转换xml
     *
     * @param obj
     * @return
     */
    public static String toXml(Object obj) {
        if (obj == null) {
            throw new IllegalArgumentException("bean转为xml，参数不能为空");
        }
        XStream xStream = new XStream(new XppDriver(new NoNameCoder()) {
            @Override
            public HierarchicalStreamWriter createWriter(Writer out) {
                return new CompactWriter(out, getNameCoder());
            }
        });
        xStream.processAnnotations(obj.getClass());
        xStream.autodetectAnnotations(true);
        xStream.aliasSystemAttribute(null, "class");
        return xStream.toXML(obj);
    }

    /**
     * 将xml转为javaBean
     *
     * @param xmlStr         xml字符串
     * @param rootClass      目标Class
     * @param interfaceClass 接口Class
     * @param implClass      实现类Class
     * @return
     */
    public static <T> T fromXml(final String xmlStr, Class<T> rootClass, Class<?> interfaceClass, Class<?> implClass) {
        if (xmlStr == null || xmlStr.isEmpty()) {
            throw new IllegalArgumentException("xml转为bean，参数xmlStr不能为空");
        }
        if (rootClass == null || interfaceClass == null || implClass == null) {
            throw new IllegalArgumentException("xml转为bean，参数class不能为空");
        }
        XStream xStream = new XStream(new DomDriver(StandardCharsets.UTF_8.name(), new XmlFriendlyNameCoder("_-", "_")));
        xStream.processAnnotations(rootClass);
        xStream.autodetectAnnotations(true);
        xStream.aliasSystemAttribute(null, "class");
        xStream.addDefaultImplementation(implClass, interfaceClass);
        xStream.addPermission(AnyTypePermission.ANY);
        xStream.ignoreUnknownElements();
        return (T) xStream.fromXML(xmlStr);
    }

}
